home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpat2-1.000 / xpat2-1 / xpat2-1.04 / src / X-arrows.c < prev    next >
C/C++ Source or Header  |  1995-01-23  |  10KB  |  316 lines

  1. /*****************************************************************************/
  2. /*                                         */
  3. /*                                         */
  4. /*    X patience version 2 -- module X-arrows.c                 */
  5. /*                                         */
  6. /*    Displays hint arrows for the X interface                 */
  7. /*    written by Heiko Eissfeldt and Michael Bischoff                 */
  8. /*    see COPYRIGHT.xpat2 for Copyright details                 */
  9. /*                                         */
  10. /*                                         */
  11. /*****************************************************************************/
  12. #include "X-pat.h"
  13.  
  14. GC hintgc;
  15. static int rem_sx = -1, rem_sy, rem_dx, rem_dy;
  16. static int size_x, size_y;
  17. static Pixmap arrow_storage_x = 0, arrow_storage_y, arrow_storage_z;
  18.  
  19. #ifdef useXlib
  20. void init_arrow(const char *arrowcolor, int arrwidth, int arrheight)
  21. {
  22.     /* make GCs for dashed lines or colored lines (to mark cards) */
  23.     XGCValues gcv;
  24.     long gcflags;
  25.     XColor color;
  26.     Colormap cmap;
  27.     
  28.     if (arrwidth >= 0 && arrwidth <= 30)
  29.     graphic.aw = arrwidth;
  30.     if (arrheight >= 0 && arrheight <= 30)
  31.     graphic.ah = arrheight;
  32.  
  33.     if (graphic.aw <= 0 || graphic.ah <= 0) {
  34.     graphic.aw = graphic.ah = -1;
  35.     return;            /* no arrows wanted */
  36.     }
  37.  
  38.     /* make own gcs for dashed lines */
  39.     gcv.background = BlackPixel(dpy, screen);
  40.     gcv.graphics_exposures = True;
  41.     gcflags = GCForeground | GCBackground | GCGraphicsExposures;
  42.     if (graphic.is_color && arrowcolor) {
  43.     cmap = DefaultColormap(dpy, screen);
  44.     color.flags = DoRed | DoGreen | DoBlue;
  45.     XAllocNamedColor(dpy, cmap, arrowcolor, &color, &color);
  46.     gcv.foreground = color.pixel;
  47.     hintgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  48.     } else {
  49.     gcv.foreground = WhitePixel(dpy, screen);
  50.     hintgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  51.     }
  52. }
  53. #endif
  54.  
  55. #ifdef useXview
  56. void init_arrow(unsigned long arrowcolor, int arrwidth, int arrheight)
  57. {
  58.     XGCValues gcv;
  59.     long gcflags;
  60.     
  61.     if (arrwidth >= 0 && arrwidth <= 30)
  62.     graphic.aw = arrwidth;
  63.     if (arrheight >= 0 && arrheight <= 30)
  64.     graphic.ah = arrheight;
  65.  
  66.     if (graphic.aw <= 0 || graphic.ah <= 0) {
  67.     graphic.aw = graphic.ah = -1;
  68.     return;            /* no arrows wanted */
  69.     }
  70.  
  71.     gcv.background = BlackPixel(dpy, screen);
  72.     gcv.graphics_exposures = True;
  73.     gcflags = GCForeground | GCBackground | GCGraphicsExposures;
  74.     gcv.foreground = arrowcolor;
  75.     hintgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  76. }
  77. #endif
  78.  
  79. /* draw an arrow with y-part */
  80. static void polygon_y(int deltax, int deltay, int adx, int ady)
  81. {
  82.     XPoint Poly[10];
  83.     Poly[0].x = rem_dx-deltax;
  84.     Poly[0].y = rem_dy-ady/2;
  85.     Poly[1].x = rem_dx-adx;
  86.     Poly[1].y = rem_dy-ady;
  87.     Poly[2].x = rem_dx;
  88.     Poly[2].y = rem_dy+ady;
  89.     Poly[3].x = rem_dx+adx;
  90.     Poly[3].y = rem_dy-ady;
  91.     Poly[4].x = rem_dx+deltax;
  92.     Poly[4].y = rem_dy-ady/2;
  93.     if (rem_dx-rem_sx > 0) {    /* this is uncritical, since difference is */
  94.         Poly[5].x = rem_dx+deltax;    /* either 0 or at least CARD_WIDTH */
  95.         Poly[5].y = rem_sy+deltay;
  96.         Poly[6].x = rem_sx-deltax;
  97.         Poly[6].y = rem_sy+deltay;
  98.         Poly[7].x = rem_sx-deltax;
  99.         Poly[7].y = rem_sy-deltay;
  100.         Poly[8].x = rem_dx-deltax;
  101.         Poly[8].y = rem_sy-deltay;
  102.         XFillPolygon(dpy, table, hintgc, Poly, 9, Complex, CoordModeOrigin);
  103.     Poly[9] = Poly[0];
  104.     XDrawLines(dpy, table, blackgc, Poly, 10, CoordModeOrigin);
  105.     } else if (rem_dx < rem_sx) {
  106.         Poly[5].x = rem_dx+deltax;
  107.         Poly[5].y = rem_sy-deltay;
  108.         Poly[6].x = rem_sx+deltax;
  109.         Poly[6].y = rem_sy-deltay;
  110.         Poly[7].x = rem_sx+deltax;
  111.         Poly[7].y = rem_sy+deltay;
  112.         Poly[8].x = rem_dx-deltax;
  113.         Poly[8].y = rem_sy+deltay;
  114.         XFillPolygon(dpy, table, hintgc, Poly, 9, Complex, CoordModeOrigin);
  115.     Poly[9] = Poly[0];
  116.     XDrawLines(dpy, table, blackgc, Poly, 10, CoordModeOrigin);
  117.     } else {
  118.         Poly[5].x = rem_sx+deltax;
  119.         Poly[5].y = rem_sy+deltay;
  120.         Poly[6].x = rem_sx-deltax;
  121.         Poly[6].y = rem_sy+deltay;
  122.         XFillPolygon(dpy, table, hintgc, Poly, 7, Complex, CoordModeOrigin);
  123.     Poly[7] = Poly[0];
  124.     XDrawLines(dpy, table, blackgc, Poly, 8, CoordModeOrigin);
  125.     }
  126. }
  127.  
  128. /* draw an x-only arrow */
  129. static void polygon_x(int deltax, int deltay, int adx, int ady)
  130. {
  131.     XPoint Poly[10];
  132.     /* Pfeil: 1      */
  133.     /*          0    */
  134.     /*             2 */
  135.     /*          4    */
  136.     /*        3      */
  137.     Poly[0].x = rem_dx-adx/2;
  138.     Poly[0].y = rem_sy-deltay;
  139.     Poly[1].x = rem_dx-adx;
  140.     Poly[1].y = rem_sy-ady;
  141.     Poly[2].x = rem_dx+adx;
  142.     Poly[2].y = rem_sy;
  143.     Poly[3].x = rem_dx-adx;
  144.     Poly[3].y = rem_sy+ady;
  145.     Poly[4].x = rem_dx-adx/2;
  146.     Poly[4].y = rem_sy+deltay;
  147.     Poly[5].x = rem_sx-deltax;
  148.     Poly[5].y = rem_sy+deltay;
  149.     Poly[6].x = rem_sx-deltax;
  150.     Poly[6].y = rem_sy-deltay;
  151.     XFillPolygon(dpy, table, hintgc, Poly, 7, Complex, CoordModeOrigin);
  152.     Poly[7] = Poly[0];
  153.     XDrawLines(dpy, table, blackgc, Poly, 8, CoordModeOrigin);
  154. }
  155.  
  156. #define UPDOWN_MINDIST    (graphic.ya_h + graphic.ah + 1)
  157.  
  158. static void display_arrow(void)
  159. {
  160.     /* build a polygon i.e. a arrow pointing from source to destination */ 
  161.  
  162.     if (rem_dy >= rem_sy + UPDOWN_MINDIST)        /* arrow up */
  163.         polygon_y(graphic.aw,-graphic.ah,graphic.ya_w, graphic.ya_h);
  164.     else if (rem_dy <= rem_sy - UPDOWN_MINDIST)    /* arrow down */
  165.         polygon_y(graphic.aw,graphic.ah,graphic.ya_w,-graphic.ya_h);
  166.     else if (rem_dx >= rem_sx)            /* arrow to the right */
  167.         polygon_x(graphic.aw,graphic.ah,graphic.xa_w,graphic.xa_h);
  168.     else                    /* arrow to the left */
  169.         polygon_x(-graphic.aw,graphic.ah,-graphic.xa_w,graphic.xa_h);
  170. }
  171.  
  172. static void clear_arrow(void)
  173. {   int a, d;
  174.     a = -1;
  175.     if (rem_sx < rem_dx) {
  176.     a = rem_sx; d = rem_dx - rem_sx;
  177.     } else if (rem_sx > rem_dx) {
  178.     a = rem_dx; d = rem_sx - rem_dx;
  179.     } else
  180.     d = a = -1;
  181.     if (a >= 0)
  182.     XCopyArea(dpy, arrow_storage_x, table, whitegc,
  183.           0, 0, d + 2 * graphic.aw + 1, 2 * graphic.ah + 1,
  184.           a - graphic.aw, rem_sy - graphic.ah);
  185.     
  186.     if (rem_sy <= rem_dy - UPDOWN_MINDIST) {
  187.     a = rem_sy; d = rem_dy - rem_sy;
  188.     } else if (rem_sy >= rem_dy + UPDOWN_MINDIST) {
  189.     a = rem_dy; d = rem_sy - rem_dy;
  190.     } else {
  191.     d = a = -1;    /* only horizontal part of arrow => y arrow */
  192.     XCopyArea(dpy, arrow_storage_z, table, whitegc,
  193.       0, 0, 2 * graphic.xa_w + 1, 2 * graphic.xa_h + 1, rem_dx-graphic.xa_w, rem_sy-graphic.xa_h);
  194.     }
  195.     if (a >= 0) {
  196.     XCopyArea(dpy, arrow_storage_y, table, whitegc,
  197.           0, 0, 2 * graphic.aw + 1, d + 2 * graphic.ah + 1,
  198.           rem_dx - graphic.aw, a - graphic.ah);
  199.     XCopyArea(dpy, arrow_storage_z, table, whitegc,
  200.       0, 0, 2 * graphic.ya_w + 1, 2 * graphic.ya_h + 1, rem_dx-graphic.ya_w, rem_dy-graphic.ya_h);
  201.     }
  202.     rem_sx = -1;
  203. }
  204.  
  205. static void save_background(void)
  206. {
  207.     /* save the background */
  208.     int a, d;
  209.     a = -1;
  210.     if (rem_sx < rem_dx) {
  211.     a = rem_sx; d = rem_dx - rem_sx;
  212.     } else if (rem_sx > rem_dx) {
  213.     a = rem_dx; d = rem_sx - rem_dx;
  214.     } else
  215.     d = a = -1;
  216.     if (a >= 0) {
  217.     int len;
  218.     len = d + 2 * graphic.aw + 1;
  219.     if (len > size_x) {    /* Create a larger Pixmap for saving */
  220.         XFreePixmap(dpy, arrow_storage_x);
  221.         arrow_storage_x = XCreatePixmap(dpy, table,
  222.           size_x = len, 2 * graphic.ah+1, DefaultDepth(dpy, screen));
  223.     }
  224.     XCopyArea(dpy, table, arrow_storage_x, whitegc,
  225.           a - graphic.aw, rem_sy - graphic.ah,
  226.           len, 2 * graphic.ah + 1, 0, 0);
  227.     }
  228.     if (rem_sy <= rem_dy - UPDOWN_MINDIST) {
  229.     a = rem_sy; d = rem_dy - rem_sy;
  230.     } else if (rem_sy >= rem_dy + UPDOWN_MINDIST) {
  231.     a = rem_dy; d = rem_sy - rem_dy;
  232.     } else {
  233.     d = a = -1;    /* only horizontal part of arrow */
  234.     XCopyArea(dpy, table, arrow_storage_z, whitegc,
  235.       rem_dx-graphic.xa_w, rem_sy-graphic.xa_h,  2 * graphic.xa_w + 1, 2 * graphic.xa_h + 1, 0, 0);
  236.     }
  237.     if (a >= 0) {
  238.     int height;
  239.     height = d + 2 * graphic.ah + 1;
  240.     if (size_y < height) {
  241.         XFreePixmap(dpy, arrow_storage_y);
  242.         arrow_storage_y = XCreatePixmap(dpy, table,
  243.         2 * graphic.aw+1, size_y = height, DefaultDepth(dpy, screen));
  244.     }
  245.     XCopyArea(dpy, table, arrow_storage_y, whitegc,
  246.           rem_dx - graphic.aw, a - graphic.ah,
  247.           2 * graphic.aw + 1, height, 0, 0);
  248.     XCopyArea(dpy, table, arrow_storage_z, whitegc,
  249.       rem_dx-graphic.ya_w, rem_dy-graphic.ya_h,  2 * graphic.ya_w + 1, 2 * graphic.ya_h + 1, 0, 0);
  250.     }
  251.  
  252. }
  253.  
  254. static void compute_rem(void) {
  255.     Pileindex srcpile;
  256.     struct pile *p;
  257.  
  258.     p = graphic.pile + game.arrow_dstpile;
  259.     srcpile = getpile(game.arrow_srcind);
  260.     rem_sx = graphic.pile[srcpile].x + CARD_WIDTH/2;
  261.     rem_sy = graphic.pile[srcpile].y + CARD_HEIGHT/2;
  262.     if (game.piletype[srcpile] == Slot) {
  263.     int y = graphic.cardy[game.arrow_srcind];
  264.     rem_sy += y;
  265.     if (game.arrow_srcind != INDEX_OF_LAST_CARD(srcpile))
  266.         rem_sy += (graphic.cardy[game.arrow_srcind+1] - y + 1) / 2
  267.                 - CARD_HEIGHT/2;
  268.     }
  269.     rem_dx = p->x + CARD_WIDTH/2;
  270.     rem_dy = p->y + CARD_HEIGHT/2;
  271.     if (game.piletype[game.arrow_dstpile] == Slot && !EMPTY(game.arrow_dstpile))
  272.     rem_dy += graphic.cardy[INDEX_OF_LAST_CARD(game.arrow_dstpile)];
  273.     if (rem_sy > graphic.height-2)
  274.     rem_sy = graphic.height-2;
  275.     if (rem_dy > graphic.height-2)
  276.     rem_dy = graphic.height-2;
  277. }
  278.  
  279. void show_arrow(int on) {
  280.     if (graphic.aw <= 0)    /* no arrows active */
  281.     return;
  282.  
  283.     if (!arrow_storage_x) {
  284.     arrow_storage_x = XCreatePixmap(dpy, table, size_x = graphic.width,
  285.             2 * graphic.ah+1, DefaultDepth(dpy, screen));
  286.     arrow_storage_y = XCreatePixmap(dpy, table, 2 * graphic.aw+1,
  287.         size_y = graphic.height, DefaultDepth(dpy, screen));
  288.     arrow_storage_z = XCreatePixmap(dpy, table, 2 * max(graphic.xa_w,
  289.         graphic.ya_w) + 1, 2 * max(graphic.xa_h, graphic.ya_h) + 1, 
  290.         DefaultDepth(dpy, screen));
  291.     }
  292.     if (on) {        /* calculate new arrow position */
  293. #ifdef DEBUG
  294.     if (on == 2)
  295.         fprintf(stderr, "arrow(2): srcind = %d\n", game.arrow_srcind);
  296. #endif
  297.     if (game.arrow_srcind < 0)
  298.         return;
  299.     if (on == 1) {
  300.         compute_rem();
  301.         save_background();
  302.     }
  303.     display_arrow();
  304. #ifdef useXview
  305.     xv_set(xv_default_server, SERVER_SYNC, FALSE, 0);
  306. #else
  307.     XFlush(dpy);
  308. #endif
  309.     } else {
  310.     game.arrow_srcind = -1;    /* no valid arrow now */
  311.     if (rem_sx < 0)
  312.         return;        /* no arrow was visible */
  313.     clear_arrow();
  314.     }
  315. }
  316.